import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DynamicParameterApp {
    private JFrame frame;
    private JPanel panel;
    private JButton addParameterButton;
    private JButton saveButton;
    private JPanel parameterPanel;
    private JScrollPane scrollPane;

    // 设置字体大小
    private static final Font FONT = new Font("微软雅黑", Font.PLAIN, 24); // 设置字体为微软雅黑，大小为24

    public DynamicParameterApp() {
        frame = new JFrame("Dynamic Parameter App");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600); // 设置窗口初始大小
        frame.setLayout(new BorderLayout());

        // 初始化按钮
        addParameterButton = new JButton("新增参数");
        saveButton = new JButton("选择保存位置");

        // 设置按钮字体
        addParameterButton.setFont(FONT);
        saveButton.setFont(FONT);

        // 按钮面板使用 GridBagLayout
        JPanel buttonPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 10, 10, 10); // 设置间距

        // 设置按钮大小
        Dimension buttonSize = new Dimension(150, 50); // 调整按钮大小
        addParameterButton.setPreferredSize(buttonSize);
        saveButton.setPreferredSize(buttonSize);

        gbc.gridx = 0;
        gbc.gridy = 0;
        buttonPanel.add(addParameterButton, gbc);

        gbc.gridx = 1;
        buttonPanel.add(saveButton, gbc);

        // 参数面板
        parameterPanel = new JPanel();
        parameterPanel.setLayout(new BoxLayout(parameterPanel, BoxLayout.Y_AXIS));

        // 添加滚动面板
        scrollPane = new JScrollPane(parameterPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.getVerticalScrollBar().setUnitIncrement(20); // 设置滚动速度

        // 添加默认参数
        addDefaultParameter();

        // 按钮事件
        addParameterButton.addActionListener(e -> addParameter());
        saveButton.addActionListener(e -> saveToFile());

        frame.add(buttonPanel, BorderLayout.NORTH);
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.setVisible(true);
    }

    private void addDefaultParameter() {
        JTextArea parameterNameField = new JTextArea(2, 15);
        JTextArea boundaryValueField = new JTextArea(2, 15);
        JCheckBox nullableCheckBox = new JCheckBox("可为空");
        parameterNameField.setText("默认参数名");
        boundaryValueField.setText("1,2,3");

        parameterNameField.setFont(FONT);
        boundaryValueField.setFont(FONT);
        nullableCheckBox.setFont(FONT);

        parameterNameField.getDocument().addDocumentListener(new TextAreaSizeListener(parameterNameField));
        boundaryValueField.getDocument().addDocumentListener(new TextAreaSizeListener(boundaryValueField));

        JPanel parameterSetPanel = new JPanel();
        parameterSetPanel.setLayout(new BoxLayout(parameterSetPanel, BoxLayout.X_AXIS));

        parameterSetPanel.add(new JLabel("参数名: "));
        parameterSetPanel.add(parameterNameField);
        parameterSetPanel.add(Box.createHorizontalStrut(10));
        parameterSetPanel.add(new JLabel("边界值取值: "));
        parameterSetPanel.add(boundaryValueField);
        parameterSetPanel.add(Box.createHorizontalStrut(10));
        parameterSetPanel.add(nullableCheckBox);

        JSeparator separator = new JSeparator();
        parameterPanel.add(parameterSetPanel);
        parameterPanel.add(separator);
        parameterPanel.revalidate();
        parameterPanel.repaint();
    }

    private void addParameter() {
        JPanel parameterSetPanel = new JPanel();
        parameterSetPanel.setLayout(new BoxLayout(parameterSetPanel, BoxLayout.X_AXIS));

        JTextArea parameterNameField = new JTextArea(2, 15);
        JTextArea boundaryValueField = new JTextArea(2, 15);
        JCheckBox nullableCheckBox = new JCheckBox("可为空");

        parameterNameField.setLineWrap(true);
        boundaryValueField.setLineWrap(true);

        parameterNameField.setFont(FONT);
        boundaryValueField.setFont(FONT);
        nullableCheckBox.setFont(FONT);

        parameterNameField.getDocument().addDocumentListener(new TextAreaSizeListener(parameterNameField));
        boundaryValueField.getDocument().addDocumentListener(new TextAreaSizeListener(boundaryValueField));

        parameterSetPanel.add(new JLabel("参数名: "));
        parameterSetPanel.add(parameterNameField);
        parameterSetPanel.add(Box.createHorizontalStrut(10));
        parameterSetPanel.add(new JLabel("边界值取值: "));
        parameterSetPanel.add(boundaryValueField);
        parameterSetPanel.add(Box.createHorizontalStrut(10));
        parameterSetPanel.add(nullableCheckBox);

        JSeparator separator = new JSeparator();
        parameterPanel.add(parameterSetPanel);
        parameterPanel.add(separator);
        parameterPanel.revalidate();
        parameterPanel.repaint();
    }

    private void saveToFile() {
//        JFileChooser fileChooser = new JFileChooser();
//        fileChooser.setDialogTitle("选择保存位置");
//        fileChooser.setFileFilter(new FileNameExtensionFilter("CSV文件", "csv"));
//        int userSelection = fileChooser.showSaveDialog(null);
//
//        if (userSelection == JFileChooser.APPROVE_OPTION) {
//            File fileToSave = fileChooser.getSelectedFile();
//            // 检查文件扩展名
//            if (!fileToSave.getName().endsWith(".csv")) {
//                fileToSave = new File(fileToSave.getAbsolutePath() + ".csv");
//            }
//
            StringBuilder csvData = new StringBuilder();
            List<String> parameterNames = new ArrayList<>(); // 存储参数名
//
        List<List<String>> parameterValues = new ArrayList<>();
        for (Component component : parameterPanel.getComponents()) {
            if (component instanceof JPanel) {
                JTextArea[] fields = new JTextArea[2];
                JCheckBox nullableCheckBox = null;
                for (Component innerComponent : ((JPanel) component).getComponents()) {
                    if (innerComponent instanceof JTextArea) {
                        for (int i = 0; i < fields.length; i++) {
                            if (fields[i] == null) {
                                fields[i] = (JTextArea) innerComponent;
                                break;
                            }
                        }
                    } else if (innerComponent instanceof JCheckBox) {
                        nullableCheckBox = (JCheckBox) innerComponent;
                    }
                }
                String parameterName = fields[0].getText(); // 第一个文本框是参数名
                parameterNames.add(parameterName); // 保存参数名
                String[] boundaryValues = fields[1].getText().split(",");
                List<String> valuesList = new ArrayList<>(Arrays.asList(boundaryValues));

                // 检查可为空复选框状态
                if (nullableCheckBox != null && nullableCheckBox.isSelected()) {
                    valuesList.add("null");
                    valuesList.add("");
                }

                parameterValues.add(valuesList);
            }
        }

        List<List<String>> cartesianProduct = new ArrayList<>();
        computeCartesianProduct(parameterValues, 0, new ArrayList<>(), cartesianProduct);

        // 添加文件头
        csvData.append(String.join(",", parameterNames)).append(",断言结果\n"); // 添加参数名和断言结果列

        for (List<String> combination : cartesianProduct) {
            csvData.append(String.join(",", combination)).append(",\n"); // 断言结果列为空
        }


        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("选择保存位置");
        fileChooser.setSelectedFile(new File("parameters.csv"));
        int userSelection = fileChooser.showSaveDialog(frame);
        if (userSelection == JFileChooser.APPROVE_OPTION) {
            File fileToSave = fileChooser.getSelectedFile();
            try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileToSave), "UTF-8"))) {
                writer.write("\uFEFF"); // 添加BOM标记解决中文乱码
                writer.write(csvData.toString());
                JOptionPane.showMessageDialog(frame, "文件已成功保存到: " + fileToSave.getAbsolutePath());
            } catch (IOException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(frame, "文件保存失败", "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void computeCartesianProduct(List<List<String>> lists, int depth, List<String> current, List<List<String>> result) {
        if (depth == lists.size()) {
            result.add(new ArrayList<>(current));
            return;
        }
        for (String element : lists.get(depth)) {
            current.add(element);
            computeCartesianProduct(lists, depth + 1, current, result);
            current.remove(current.size() - 1);
        }
    }

    private class TextAreaSizeListener implements DocumentListener {
        private final JTextArea textArea;

        public TextAreaSizeListener(JTextArea textArea) {
            this.textArea = textArea;
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            adjustSize();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            adjustSize();
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            adjustSize();
        }

        private void adjustSize() {
            int lineCount = textArea.getLineCount();
            textArea.setRows(lineCount);
            textArea.revalidate();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(DynamicParameterApp::new);
    }
}
